<!DOCTYPE html>
<html lang="zh">

<head>
  <!-- Required meta tags -->
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
  <title>星级管理系统</title>
  <!-- plugins:css -->
  <link rel="stylesheet" href="../../vendors/feather/feather.css">
  <link rel="stylesheet" href="../../vendors/mdi/css/materialdesignicons.min.css">
  <link rel="stylesheet" href="../../vendors/ti-icons/css/themify-icons.css">
  <link rel="stylesheet" href="../../vendors/typicons/typicons.css">
  <link rel="stylesheet" href="../../vendors/simple-line-icons/css/simple-line-icons.css">
  <link rel="stylesheet" href="../../vendors/css/vendor.bundle.base.css">
  <!-- endinject -->
  <!-- Plugin css for this page -->
  <!-- End plugin css for this page -->
  <!-- inject:css -->
  <link rel="stylesheet" href="../../css/vertical-layout-light/style.css">
  <!-- endinject -->
  <link rel="shortcut icon" href="../../images/favicon.png" />
  <style>
    .seat-map-container {
      position: relative;
      width: 100%;
      height: 600px;
      background: transparent; /* 隐藏背景 */
      border: 2px solid #ddd; /* 显示边框 */
      margin: 20px 0;
      overflow: hidden; /* 移除滚动条 */
    }
    .seat-item {
      position: absolute;
      cursor: move;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: center;
      transition: left 0.3s ease, top 0.3s ease; /* 优化拖动动画 */
      width: 100px;
      height: 60px;
      border-radius: 4px;
      z-index: 10;
    }
    .single-seat {
      background: #4CAF50;
    }
    .seat-number {
      color: white;
      font-weight: bold;
      margin-bottom: 4px;
    }
    .edit-btn {
      padding: 2px 8px;
      font-size: 12px;
      border-radius: 3px;
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      opacity: 0;
      transition: opacity 0.2s ease;
    }
    .seat-item:hover .edit-btn,
    .module-item:hover .edit-btn {
      opacity: 1;
    }
    .grid-container {
      position: absolute;
      top: 0;
      left: 0;
      width: 1200px; /* 12列 x 100px */
      height: 600px; /* 10行 x 60px */
      display: grid;
      z-index: 1;
    }
    .grid-cell {
      border: 1px dashed #ccc;
      position: relative;
    }
    .grid-cell-center {
      position: absolute;
      width: 8px;
      height: 8px;
      background: rgba(0, 0, 255, 0.3);
      border-radius: 50%;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      z-index: 5;
    }
    .grid-cell-label {
      position: absolute;
      font-size: 10px;
      color: #999;
      bottom: 2px;
      right: 2px;
    }
    /* 编辑模式相关样式 */
    .edit-mode-container {
      margin-top: 10px;
      margin-bottom: 15px;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    .edit-mode-label {
      font-weight: 600;
      font-size: 16px;
      color: #555;
    }
    .form-switch .form-check-input {
      width: 3em;
      height: 1.5em;
      cursor: pointer;
    }
    .form-check-input:checked {
      background-color: #198754;
      border-color: #198754;
    }
    /* 隐藏网格元素（在非编辑模式下） */
    .hide-grid .grid-cell {
      border-color: transparent;
    }
    .hide-grid .grid-cell-center,
    .hide-grid .grid-cell-label {
      display: none;
    }
    .flash {
      animation: flash-animation 0.5s ease-in-out;
    }
    @keyframes flash-animation {
      0% { opacity: 1; }
      50% { opacity: 0.5; }
      100% { opacity: 1; }
    }
    .offline {
      background-color: #888888;
    }
    .maintenance {
      background-color: #FFA500;
    }
    .online {
      background-color: #4CAF50;
    }
    /* 自定义模块样式 */
    .module-item {
      position: absolute;
      cursor: move;
      display: flex;
      align-items: center;
      justify-content: center;
      transition: left 0.3s ease, top 0.3s ease;
      width: 100px;
      height: 60px;
      border-radius: 4px;
      z-index: 10;
      color: white;
      font-weight: bold;
    }
    .delete-icon {
      position: absolute;
      left: 5px;
      top: 5px;
      width: 12px;
      height: 12px;
      background-color: #ff0000;
      border-radius: 50%;
      cursor: pointer;
      z-index: 11;
      box-shadow: 0 1px 3px rgba(0,0,0,0.3);
    }
    /* 自定义警告弹窗 */
    .custom-alert {
      position: fixed;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      background-color: white;
      padding: 20px;
      border-radius: 8px;
      box-shadow: 0 5px 15px rgba(0,0,0,0.3);
      z-index: 1050;
      min-width: 300px;
      text-align: center;
      display: none;
    }
    .custom-alert-title {
      font-size: 18px;
      margin-bottom: 10px;
      font-weight: bold;
    }
    .custom-alert-message {
      margin-bottom: 15px;
    }
    .custom-alert-buttons {
      display: flex;
      justify-content: center;
      gap: 10px;
    }
    .custom-alert-overlay {
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(0,0,0,0.5);
      z-index: 1040;
      display: none;
    }
    .wall {
      background-color: #6c757d; /* 灰色 */
    }
    .entrance {
      background-color: #28a745; /* 浅绿色 */
    }
    .testing {
      background-color: #ffc107; /* 黄色 */
    }
    .stairs {
      background-color: #17a2b8; /* 浅蓝色 */
    }
    .toilet {
      background-color: #1e7e34; /* 深绿色 */
    }
    .reception {
      background-color: #fd7e14; /* 暖心橙 */
    }
    .floor-selector {
      margin-bottom: 10px;
      display: flex;
      align-items: center;
      gap: 10px;
    }
    .floor-btn {
      margin-right: 5px;
    }
    .floor-btn.active {
      background-color: #007bff;
      color: white;
    }
  </style>
</head>

<body>
<div class="container-scroller">
  <!-- partial:../../partials/_navbar.html -->
  <nav class="navbar default-layout col-lg-12 col-12 p-0 fixed-top d-flex align-items-top flex-row">
    <div class="text-center navbar-brand-wrapper d-flex align-items-center justify-content-start">
      <div class="me-3">
        <button class="navbar-toggler navbar-toggler align-self-center" type="button" data-bs-toggle="minimize">
          <span class="icon-menu"></span>
        </button>
      </div>
      <div>
        <a class="navbar-brand brand-logo" href="../../index.html">
          <img src="../../images/logo.svg" alt="logo" />
        </a>
        <a class="navbar-brand brand-logo-mini" href="../../index.html">
          <img src="../../images/logo-mini.svg" alt="logo" />
        </a>
      </div>
    </div>
    <div class="navbar-menu-wrapper d-flex align-items-top">
      <ul class="navbar-nav">
        <li class="nav-item font-weight-semibold d-none d-lg-block ms-0">
          <h1 class="welcome-text">早上好，<span class="text-black fw-bold">约翰·多</span></h1>
          <h3 class="welcome-sub-text">您本周的表现摘要</h3>
        </li>
      </ul>
      <ul class="navbar-nav ms-auto">
        <li class="nav-item dropdown d-none d-lg-block">
          <a class="nav-link dropdown-bordered dropdown-toggle dropdown-toggle-split" id="messageDropdown" href="#" data-bs-toggle="dropdown" aria-expanded="false"> 选择类别 </a>
          <div class="dropdown-menu dropdown-menu-right navbar-dropdown preview-list pb-0" aria-labelledby="messageDropdown">
            <a class="dropdown-item py-3">
              <p class="mb-0 font-weight-medium float-left">选择类别</p>
            </a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item preview-item">
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">Bootstrap 套件</p>
                <p class="fw-light small-text mb-0">这是一个包含 16 个独特仪表板的套件</p>
              </div>
            </a>
            <a class="dropdown-item preview-item">
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">Angular 套件</p>
                <p class="fw-light small-text mb-0">您 Angular 项目所需的一切</p>
              </div>
            </a>
            <a class="dropdown-item preview-item">
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">VUE 套件</p>
                <p class="fw-light small-text mb-0">6 个高级 Vue 管理仪表板的套件</p>
              </div>
            </a>
            <a class="dropdown-item preview-item">
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">React 套件</p>
                <p class="fw-light small-text mb-0">8 个高级 React 管理仪表板的套件</p>
              </div>
            </a>
          </div>
        </li>
        <li class="nav-item d-none d-lg-block">
          <div id="datepicker-popup" class="input-group date datepicker navbar-date-picker">
              <span class="input-group-addon input-group-prepend border-right">
                <span class="icon-calendar input-group-text calendar-icon"></span>
              </span>
            <input type="text" class="form-control">
          </div>
        </li>
        <li class="nav-item">
          <form class="search-form" action="#">
            <i class="icon-search"></i>
            <input type="search" class="form-control" placeholder="搜索这里" title="搜索这里">
          </form>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link count-indicator" id="notificationDropdown" href="#" data-bs-toggle="dropdown">
            <i class="icon-mail icon-lg"></i>
          </a>
          <div class="dropdown-menu dropdown-menu-right navbar-dropdown preview-list pb-0" aria-labelledby="notificationDropdown">
            <a class="dropdown-item py-3 border-bottom">
              <p class="mb-0 font-weight-medium float-left">您有 4 条新通知</p>
              <span class="badge badge-pill badge-primary float-right">查看全部</span>
            </a>
            <a class="dropdown-item preview-item py-3">
              <div class="preview-thumbnail">
                <i class="mdi mdi-alert m-auto text-primary"></i>
              </div>
              <div class="preview-item-content">
                <h6 class="preview-subject fw-normal text-dark mb-1">应用程序错误</h6>
                <p class="fw-light small-text mb-0">刚刚</p>
              </div>
            </a>
            <a class="dropdown-item preview-item py-3">
              <div class="preview-thumbnail">
                <i class="mdi mdi-settings m-auto text-primary"></i>
              </div>
              <div class="preview-item-content">
                <h6 class="preview-subject fw-normal text-dark mb-1">设置</h6>
                <p class="fw-light small-text mb-0">私人消息</p>
              </div>
            </a>
            <a class="dropdown-item preview-item py-3">
              <div class="preview-thumbnail">
                <i class="mdi mdi-airballoon m-auto text-primary"></i>
              </div>
              <div class="preview-item-content">
                <h6 class="preview-subject fw-normal text-dark mb-1">新用户注册</h6>
                <p class="fw-light small-text mb-0">2 天前</p>
              </div>
            </a>
          </div>
        </li>
        <li class="nav-item dropdown">
          <a class="nav-link count-indicator" id="countDropdown" href="#" data-bs-toggle="dropdown" aria-expanded="false">
            <i class="icon-bell"></i>
            <span class="count"></span>
          </a>
          <div class="dropdown-menu dropdown-menu-right navbar-dropdown preview-list pb-0" aria-labelledby="countDropdown">
            <a class="dropdown-item py-3">
              <p class="mb-0 font-weight-medium float-left">您有 7 封未读邮件</p>
              <span class="badge badge-pill badge-primary float-right">查看全部</span>
            </a>
            <div class="dropdown-divider"></div>
            <a class="dropdown-item preview-item">
              <div class="preview-thumbnail">
                <img src="../../images/faces/face10.jpg" alt="image" class="img-sm profile-pic">
              </div>
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">玛丽安·加纳</p>
                <p class="fw-light small-text mb-0">会议已取消</p>
              </div>
            </a>
            <a class="dropdown-item preview-item">
              <div class="preview-thumbnail">
                <img src="../../images/faces/face12.jpg" alt="image" class="img-sm profile-pic">
              </div>
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">大卫·格雷</p>
                <p class="fw-light small-text mb-0">会议已取消</p>
              </div>
            </a>
            <a class="dropdown-item preview-item">
              <div class="preview-thumbnail">
                <img src="../../images/faces/face1.jpg" alt="image" class="img-sm profile-pic">
              </div>
              <div class="preview-item-content flex-grow py-2">
                <p class="preview-subject ellipsis font-weight-medium text-dark">特拉维斯·詹金斯</p>
                <p class="fw-light small-text mb-0">会议已取消</p>
              </div>
            </a>
          </div>
        </li>
        <li class="nav-item dropdown d-none d-lg-block user-dropdown">
          <a class="nav-link" id="UserDropdown" href="#" data-bs-toggle="dropdown" aria-expanded="false">
            <img class="img-xs rounded-circle" src="../../images/faces/face8.jpg" alt="Profile image"> </a>
          <div class="dropdown-menu dropdown-menu-right navbar-dropdown" aria-labelledby="UserDropdown">
            <div class="dropdown-header text-center">
              <img class="img-md rounded-circle" src="../../images/faces/face8.jpg" alt="Profile image">
              <p class="mb-1 mt-3 font-weight-semibold">艾伦·莫雷诺</p>
              <p class="fw-light text-muted mb-0">allenmoreno@gmail.com</p>
            </div>
            <a class="dropdown-item"><i class="dropdown-item-icon mdi mdi-account-outline text-primary me-2"></i> 我的资料 <span class="badge badge-pill badge-danger">1</span></a>
            <a class="dropdown-item"><i class="dropdown-item-icon mdi mdi-message-text-outline text-primary me-2"></i> 消息</a>
            <a class="dropdown-item"><i class="dropdown-item-icon mdi mdi-calendar-check-outline text-primary me-2"></i> 活动</a>
            <a class="dropdown-item"><i class="dropdown-item-icon mdi mdi-help-circle-outline text-primary me-2"></i> 常见问题</a>
            <a class="dropdown-item"><i class="dropdown-item-icon mdi mdi-power text-primary me-2"></i> 登出</a>
          </div>
        </li>
      </ul>
      <button class="navbar-toggler navbar-toggler-right d-lg-none align-self-center" type="button" data-bs-toggle="offcanvas">
        <span class="mdi mdi-menu"></span>
      </button>
    </div>
  </nav>
  <!-- partial -->
  <div class="container-fluid page-body-wrapper">
    <!-- partial:../../partials/_settings-panel.html -->
    <div class="theme-setting-wrapper">
      <div id="settings-trigger"><i class="ti-settings"></i></div>
      <div id="theme-settings" class="settings-panel">
        <i class="settings-close ti-close"></i>
        <p class="settings-heading">侧边栏皮肤</p>
        <div class="sidebar-bg-options selected" id="sidebar-light-theme"><div class="img-ss rounded-circle bg-light border me-3"></div>浅色</div>
        <div class="sidebar-bg-options" id="sidebar-dark-theme"><div class="img-ss rounded-circle bg-dark border me-3"></div>深色</div>
        <p class="settings-heading mt-2">头部皮肤</p>
        <div class="color-tiles mx-0 px-4">
          <div class="tiles success"></div>
          <div class="tiles warning"></div>
          <div class="tiles danger"></div>
          <div class="tiles info"></div>
          <div class="tiles dark"></div>
          <div class="tiles default"></div>
        </div>
      </div>
    </div>
    <div id="right-sidebar" class="settings-panel">
      <i class="settings-close ti-close"></i>
      <ul class="nav nav-tabs border-top" id="setting-panel" role="tablist">
        <li class="nav-item">
          <a class="nav-link active" id="todo-tab" data-bs-toggle="tab" href="#todo-section" role="tab" aria-controls="todo-section" aria-expanded="true">待办事项</a>
        </li>
        <li class="nav-item">
          <a class="nav-link" id="chats-tab" data-bs-toggle="tab" href="#chats-section" role="tab" aria-controls="chats-section">聊天</a>
        </li>
      </ul>
      <div class="tab-content" id="setting-content">
        <div class="tab-pane fade show active scroll-wrapper" id="todo-section" role="tabpanel" aria-labelledby="todo-section">
          <div class="add-items d-flex px-3 mb-0">
            <form class="form w-100">
              <div class="form-group d-flex">
                <input type="text" class="form-control todo-list-input" placeholder="添加待办事项">
                <button type="submit" class="add btn btn-primary todo-list-add-btn" id="add-task">添加</button>
              </div>
            </form>
          </div>
          <div class="list-wrapper px-3">
            <ul class="d-flex flex-column-reverse todo-list">
              <li>
                <div class="form-check">
                  <label class="form-check-label">
                    <input class="checkbox" type="checkbox">
                    团队评审会议在下午 3 点
                  </label>
                </div>
                <i class="remove ti-close"></i>
              </li>
              <li>
                <div class="form-check">
                  <label class="form-check-label">
                    <input class="checkbox" type="checkbox">
                    准备演示
                  </label>
                </div>
                <i class="remove ti-close"></i>
              </li>
              <li>
                <div class="form-check">
                  <label class="form-check-label">
                    <input class="checkbox" type="checkbox">
                    解决所有今天到期的低优先级票据
                  </label>
                </div>
                <i class="remove ti-close"></i>
              </li>
              <li class="completed">
                <div class="form-check">
                  <label class="form-check-label">
                    <input class="checkbox" type="checkbox" checked>
                    安排下周的会议
                  </label>
                </div>
                <i class="remove ti-close"></i>
              </li>
              <li class="completed">
                <div class="form-check">
                  <label class="form-check-label">
                    <input class="checkbox" type="checkbox" checked>
                    项目评审
                  </label>
                </div>
                <i class="remove ti-close"></i>
              </li>
            </ul>
          </div>
          <h4 class="px-3 text-muted mt-5 fw-light mb-0">事件</h4>
          <div class="events pt-4 px-3">
            <div class="wrapper d-flex mb-2">
              <i class="ti-control-record text-primary me-2"></i>
              <span>2018年2月11日</span>
            </div>
            <p class="mb-0 font-weight-thin text-gray">创建组件页面构建 js</p>
            <p class="text-gray mb-0">会话总数</p>
          </div>
          <div class="events pt-4 px-3">
            <div class="wrapper d-flex mb-2">
              <i class="ti-control-record text-primary me-2"></i>
              <span>2018年2月7日</span>
            </div>
            <p class="mb-0 font-weight-thin text-gray">与阿丽莎的会议</p>
            <p class="text-gray mb-0 ">给莎拉·格雷打电话</p>
          </div>
        </div>
        <!-- To do section tab ends -->
        <div class="tab-pane fade" id="chats-section" role="tabpanel" aria-labelledby="chats-section">
          <div class="d-flex align-items-center justify-content-between border-bottom">
            <p class="settings-heading border-top-0 mb-3 pl-3 pt-0 border-bottom-0 pb-0">朋友</p>
            <small class="settings-heading border-top-0 mb-3 pt-0 border-bottom-0 pb-0 pr-3 fw-normal">查看全部</small>
          </div>
          <ul class="chat-list">
            <li class="list active">
              <div class="profile"><img src="../../images/faces/face1.jpg" alt="image"><span class="online"></span></div>
              <div class="info">
                <p>托马斯·道格拉斯</p>
                <p>可用</p>
              </div>
              <small class="text-muted my-auto">19 分钟前</small>
            </li>
            <li class="list">
              <div class="profile"><img src="../../images/faces/face2.jpg" alt="image"><span class="offline"></span></div>
              <div class="info">
                <div class="wrapper d-flex">
                  <p>凯瑟琳</p>
                </div>
                <p>离开</p>
              </div>
              <div class="badge badge-success badge-pill my-auto mx-2">4</div>
              <small class="text-muted my-auto">23 分钟前</small>
            </li>
            <li class="list">
              <div class="profile"><img src="../../images/faces/face3.jpg" alt="image"><span class="online"></span></div>
              <div class="info">
                <p>丹尼尔·拉塞尔</p>
                <p>可用</p>
              </div>
              <small class="text-muted my-auto">14 分钟前</small>
            </li>
            <li class="list">
              <div class="profile"><img src="../../images/faces/face4.jpg" alt="image"><span class="offline"></span></div>
              <div class="info">
                <p>詹姆斯·理查森</p>
                <p>离开</p>
              </div>
              <small class="text-muted my-auto">2 分钟前</small>
            </li>
            <li class="list">
              <div class="profile"><img src="../../images/faces/face5.jpg" alt="image"><span class="online"></span></div>
              <div class="info">
                <p>麦德琳·肯尼迪</p>
                <p>可用</p>
              </div>
              <small class="text-muted my-auto">5 分钟前</small>
            </li>
            <li class="list">
              <div class="profile"><img src="../../images/faces/face6.jpg" alt="image"><span class="online"></span></div>
              <div class="info">
                <p>莎拉·格雷夫斯</p>
                <p>可用</p>
              </div>
              <small class="text-muted my-auto">47 分钟前</small>
            </li>
          </ul>
        </div>
        <!-- chat tab ends -->
      </div>
    </div>
    <!-- partial -->
    <!-- partial:../../partials/_sidebar.html -->
    <nav class="sidebar sidebar-offcanvas" id="sidebar">
      <ul class="nav">
        <li class="nav-item">
          <a class="nav-link" href="../../index.html">
            <i class="mdi mdi-grid-large menu-icon"></i>
            <span class="menu-title">仪表盘</span>
          </a>
        </li>

        <li class="nav-item nav-category">管理员操作</li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#ui-sb" aria-expanded="false" aria-controls="ui-sb">
            <i class="menu-icon mdi mdi-floor-plan"></i>
            <span class="menu-title">设备管理</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="ui-sb">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="pages/equipment-management/status.html">设备状态</a></li>
            </ul>
          </div>
        </li>

        <li class="nav-item nav-category">UI 元素</li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#ui-basic" aria-expanded="false" aria-controls="ui-basic">
            <i class="menu-icon mdi mdi-floor-plan"></i>
            <span class="menu-title">UI 元素</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="ui-basic">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="../../pages/ui-features/buttons.html">按钮</a></li>
              <li class="nav-item"> <a class="nav-link" href="../../pages/ui-features/dropdowns.html">下拉菜单</a></li>
              <li class="nav-item"> <a class="nav-link" href="../../pages/ui-features/typography.html">排版</a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item nav-category">表单和数据</li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#form-elements" aria-expanded="false" aria-controls="form-elements">
            <i class="menu-icon mdi mdi-card-text-outline"></i>
            <span class="menu-title">表单元素</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="form-elements">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"><a class="nav-link" href="../../pages/forms/basic_elements.html">基本元素</a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#charts" aria-expanded="false" aria-controls="charts">
            <i class="menu-icon mdi mdi-chart-line"></i>
            <span class="menu-title">图表</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="charts">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="../../pages/charts/chartjs.html">ChartJs</a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#tables" aria-expanded="false" aria-controls="tables">
            <i class="menu-icon mdi mdi-table"></i>
            <span class="menu-title">表格</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="tables">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="../../pages/tables/basic-table.html">基本表格</a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#icons" aria-expanded="false" aria-controls="icons">
            <i class="menu-icon mdi mdi-layers-outline"></i>
            <span class="menu-title">图标</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="icons">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="../../pages/icons/mdi.html">Mdi 图标</a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item nav-category">页面</li>
        <li class="nav-item">
          <a class="nav-link" data-bs-toggle="collapse" href="#auth" aria-expanded="false" aria-controls="auth">
            <i class="menu-icon mdi mdi-account-circle-outline"></i>
            <span class="menu-title">用户页面</span>
            <i class="menu-arrow"></i>
          </a>
          <div class="collapse" id="auth">
            <ul class="nav flex-column sub-menu">
              <li class="nav-item"> <a class="nav-link" href="../../pages/samples/login.html"> 登录 </a></li>
            </ul>
          </div>
        </li>
        <li class="nav-item nav-category">帮助</li>
        <li class="nav-item">
          <a class="nav-link" href="#">
            <i class="menu-icon mdi mdi-file-document"></i>
            <span class="menu-title">文档</span>
          </a>
        </li>
      </ul>
    </nav>
    <!-- partial -->
    <!--主部分-->
    <div class="main-panel">
      <div class="container-scroller">
        <!-- 继承原有导航栏 -->
        <!-- partial:../../partials/_navbar.html -->

        <div class="container-fluid page-body-wrapper">
          <!-- 主内容区 -->
          <div class="main-panel">
            <div class="content-wrapper">
              <div class="row">
                <div class="col-12">
                  <h4 class="card-title">网吧座位布局编辑器</h4>
                  <div class="floor-selector">
                    <button id="floor1" class="btn btn-outline-primary floor-btn active">1楼</button>
                    <button id="floor2" class="btn btn-outline-primary floor-btn">2楼</button>
                  </div>
                  <div class="mb-3 edit-mode-container">
                    <div class="form-check form-switch d-flex align-items-center">
                      <input class="form-check-input me-2" type="checkbox" id="editModeSwitch">
                      <label class="form-check-label edit-mode-label" for="editModeSwitch">编辑模式</label>
                    </div>
                  </div>
                  <div id="editControls" style="display: none;">
                    <button id="addSingleSeat" class="btn btn-success ms-2">添加座位</button>
                    <button id="addCustomModule" class="btn btn-primary ms-2">添加模块</button>
                    <button id="exportLayout" class="btn btn-info ms-2">导出布局</button>
                    <button id="importLayout" class="btn btn-warning ms-2">导入布局</button>
                    <button id="clearLayout" class="btn btn-danger ms-2">清空布局</button>
                  </div>
                  <div class="seat-map-container" id="seatMap">
                    <div class="grid-container" id="gridContainer"></div>
                  </div>

                  <!-- 编辑模态框 -->
                  <div class="modal fade" id="editModal">
                    <div class="modal-dialog">
                      <div class="modal-content">
                        <div class="modal-header">
                          <h5 class="modal-title">座位设置</h5>
                        </div>
                        <div class="modal-body">
                          <div class="form-group">
                            <label>名称</label>
                            <input type="text" class="form-control" id="seatNumber">
                          </div>
                          <div class="form-group" id="statusGroup">
                            <label>设备状态</label>
                            <select class="form-control" id="seatStatus">
                              <option value="online">在线</option>
                              <option value="offline">离线</option>
                              <option value="maintenance">维修中</option>
                            </select>
                          </div>
                          <div class="form-group" id="moduleTypeGroup" style="display: none;">
                            <label>模块类型</label>
                            <select class="form-control" id="moduleType">
                              <option value="wall">墙体</option>
                              <option value="entrance">出入口</option>
                              <option value="testing">测试区</option>
                              <option value="stairs">楼梯</option>
                              <option value="toilet">厕所</option>
                              <option value="reception">前台</option>
                            </select>
                          </div>
                        </div>
                        <div class="modal-footer">
                          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
                          <button type="button" class="btn btn-primary" id="saveChanges">保存</button>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- 自定义警告弹窗 -->
      <div class="custom-alert-overlay" id="alertOverlay"></div>
      <div class="custom-alert" id="customAlert">
        <div class="custom-alert-title" id="alertTitle">警告</div>
        <div class="custom-alert-message" id="alertMessage">确定执行此操作吗？</div>
        <div class="custom-alert-buttons">
          <button class="btn btn-secondary" id="alertCancel">取消</button>
          <button class="btn btn-primary" id="alertConfirm">确认</button>
        </div>
      </div>

      <!-- content-wrapper ends -->
      <!-- partial:../../partials/_footer.html -->
      <footer class="footer">
        <div class="d-sm-flex justify-content-center justify-content-sm-between">
          <span class="float-none float-sm-right d-block mt-1 mt-sm-0 text-center">版权所有 © 模板。保留所有权利。</span>
        </div>
      </footer>
      <!-- partial -->
    </div>
    <!-- main-panel ends -->
  </div>
  <!-- page-body-wrapper ends -->
</div>
<!-- container-scroller -->
<!-- plugins:js -->
<script src="../../vendors/js/vendor.bundle.base.js"></script>
<!-- endinject -->
<!-- Plugin js for this page -->
<script src="../../vendors/bootstrap-datepicker/bootstrap-datepicker.min.js"></script>
<!-- End plugin js for this page -->
<!-- inject:js -->
<script src="../../js/off-canvas.js"></script>
<script src="../../js/hoverable-collapse.js"></script>
<script src="../../js/template.js"></script>
<script src="../../js/settings.js"></script>
<script src="../../js/todolist.js"></script>
<!-- 引入本地 jQuery 和 Bootstrap JS -->
<script src="../../js/jquery-3.7.1.min.js"></script>
<script src="../../js/bootstrap.min.js"></script>
<!-- endinject -->
<!-- 座位管理-->
<script>
  class SeatManager {
    constructor() {
      this.nextId = 1;
      this.seats = {
        floor1: [],
        floor2: []
      };
      this.modules = {
        floor1: [],
        floor2: []
      };
      this.currentSeat = null;
      this.currentModule = null;
      this.isEditingModule = false;
      this.editMode = false; // 默认关闭编辑模式
      this.cellSize = 100; // 网格单元格大小
      this.cellHeight = 60; // 网格单元格高度
      this.gridRows = 10; // 网格行数
      this.gridCols = 12; // 网格列数
      this.currentFloor = 'floor1'; // 当前选中的楼层
      
      // 从本地存储加载数据
      this.loadFromLocalStorage();
      this.initGrid();
      this.renderSeats();
      this.renderModules();
      this.setupEventListeners();
      
      // 初始化编辑模式UI状态
      document.getElementById('editModeSwitch').checked = this.editMode;
      document.getElementById('editControls').style.display = this.editMode ? 'block' : 'none';
      
      // 根据编辑模式设置网格显示/隐藏
      const gridContainer = document.getElementById('gridContainer').parentElement;
      if (this.editMode) {
        gridContainer.classList.remove('hide-grid');
      } else {
        gridContainer.classList.add('hide-grid');
      }
      
      // 防止拖动时的文本选择
      this.preventTextSelection();
      
      // 初始化自定义弹窗事件
      this.initCustomAlert();
    }
    
    // 防止文本选择
    preventTextSelection() {
      // 添加全局样式以防止文本选择
      const style = document.createElement('style');
      style.textContent = `
        .seat-map-container * {
          -webkit-user-select: none;
          -moz-user-select: none;
          -ms-user-select: none;
          user-select: none;
        }
        .seat-item, .module-item {
          touch-action: none; /* 防止触摸设备上的默认行为 */
        }
      `;
      document.head.appendChild(style);
    }

    initGrid() {
      const gridContainer = document.getElementById('gridContainer');
      gridContainer.style.gridTemplateColumns = `repeat(${this.gridCols}, ${this.cellSize}px)`;
      gridContainer.style.gridTemplateRows = `repeat(${this.gridRows}, ${this.cellHeight}px)`;
      gridContainer.style.width = `${this.gridCols * this.cellSize}px`;
      gridContainer.style.height = `${this.gridRows * this.cellHeight}px`;
      
      // 清空网格
      gridContainer.innerHTML = '';
      
      // 创建网格单元格
      for (let row = 0; row < this.gridRows; row++) {
        for (let col = 0; col < this.gridCols; col++) {
          const cell = document.createElement('div');
          cell.className = 'grid-cell';
          cell.dataset.row = row;
          cell.dataset.col = col;
          
          // 添加中心点
          const center = document.createElement('div');
          center.className = 'grid-cell-center';
          cell.appendChild(center);
          
          // 添加坐标标签
          const label = document.createElement('div');
          label.className = 'grid-cell-label';
          label.textContent = `${row}:${col}`;
          cell.appendChild(label);
          
          gridContainer.appendChild(cell);
        }
      }
    }

    loadFromLocalStorage() {
      try {
        // 加载1楼数据
        const savedSeatsFloor1 = localStorage.getItem('seats_floor1');
        if (savedSeatsFloor1) {
          this.seats.floor1 = JSON.parse(savedSeatsFloor1);
        }
        
        // 加载2楼数据
        const savedSeatsFloor2 = localStorage.getItem('seats_floor2');
        if (savedSeatsFloor2) {
          this.seats.floor2 = JSON.parse(savedSeatsFloor2);
        }
        
        // 加载模块数据
        const savedModulesFloor1 = localStorage.getItem('modules_floor1');
        if (savedModulesFloor1) {
          this.modules.floor1 = JSON.parse(savedModulesFloor1);
        }
        
        const savedModulesFloor2 = localStorage.getItem('modules_floor2');
        if (savedModulesFloor2) {
          this.modules.floor2 = JSON.parse(savedModulesFloor2);
        }
        
        // 找出最大ID，确保新添加的座位/模块ID不重复
        const allItems = [...this.seats.floor1, ...this.seats.floor2, ...this.modules.floor1, ...this.modules.floor2];
        if (allItems.length > 0) {
          const maxId = Math.max(...allItems.map(item => item.id));
          this.nextId = maxId + 1;
        }
      } catch (error) {
        console.error('加载数据失败:', error);
        this.seats = { floor1: [], floor2: [] };
        this.modules = { floor1: [], floor2: [] };
      }
    }

    renderSeats() {
      const container = document.getElementById('seatMap');
      // 移除所有现有座位元素（保留网格）
      const existingSeats = container.querySelectorAll('.seat-item');
      existingSeats.forEach(seat => seat.remove());
      
      // 使用文档片段提高性能
      const fragment = document.createDocumentFragment();
      
      // 获取当前楼层的座位
      const currentFloorSeats = this.seats[this.currentFloor];

      currentFloorSeats.forEach(seat => {
        const seatEl = document.createElement('div');
        seatEl.className = `seat-item ${seat.status || 'online'} single-seat`;
        
        // 根据网格坐标计算像素位置
        const x = seat.col * this.cellSize;
        const y = seat.row * this.cellHeight;
        
        seatEl.style.left = `${x}px`;
        seatEl.style.top = `${y}px`;
        
        // 根据编辑模式设置cursor样式
        seatEl.style.cursor = this.editMode ? 'move' : 'default';
        
        // 构建HTML内容
        let innerHTML = `<span class="seat-number">${seat.number}</span>`;
        
        // 只在编辑模式下显示编辑和删除按钮
        if (this.editMode) {
          innerHTML += `
            <div class="delete-icon" data-id="${seat.id}" data-type="seat"></div>
            <button class="btn btn-light edit-btn" data-id="${seat.id}" data-type="seat">编辑</button>
          `;
        }
        
        seatEl.innerHTML = innerHTML;
        fragment.appendChild(seatEl);
      });
      
      container.appendChild(fragment);
      
      // 更新楼层按钮状态
      document.querySelectorAll('.floor-btn').forEach(btn => {
        btn.classList.remove('active');
      });
      document.getElementById(this.currentFloor).classList.add('active');
    }
    
    renderModules() {
      const container = document.getElementById('seatMap');
      // 移除所有现有模块元素
      const existingModules = container.querySelectorAll('.module-item');
      existingModules.forEach(module => module.remove());
      
      // 使用文档片段提高性能
      const fragment = document.createDocumentFragment();
      
      // 获取当前楼层的模块
      const currentFloorModules = this.modules[this.currentFloor];

      currentFloorModules.forEach(module => {
        const moduleEl = document.createElement('div');
        moduleEl.className = `module-item ${module.type || 'wall'}`;
        
        // 根据网格坐标计算像素位置
        const x = module.col * this.cellSize;
        const y = module.row * this.cellHeight;
        
        moduleEl.style.left = `${x}px`;
        moduleEl.style.top = `${y}px`;
        
        // 根据编辑模式设置cursor样式
        moduleEl.style.cursor = this.editMode ? 'move' : 'default';
        
        // 构建HTML内容
        let innerHTML = `<span class="module-name">${module.name}</span>`;
        
        // 只在编辑模式下显示编辑和删除按钮
        if (this.editMode) {
          innerHTML += `
            <div class="delete-icon" data-id="${module.id}" data-type="module"></div>
            <button class="btn btn-light edit-btn" data-id="${module.id}" data-type="module">编辑</button>
          `;
        }
        
        moduleEl.innerHTML = innerHTML;
        fragment.appendChild(moduleEl);
      });
      
      container.appendChild(fragment);
    }
    
    setupEventListeners() {
      // 使用事件委托减少事件监听器数量
      const seatMap = document.getElementById('seatMap');
      
      // 拖动功能
      let isDragging = false;
      let currentEl = null;
      let startX, startY, initialX, initialY;
      let elementType = null;

      // 添加按钮事件
      document.getElementById('addSingleSeat').addEventListener('click', () => this.addSeat());
      document.getElementById('addCustomModule').addEventListener('click', () => this.addCustomModule());
      document.getElementById('exportLayout').addEventListener('click', () => this.exportLayout());
      document.getElementById('importLayout').addEventListener('click', () => this.handleImport());
      
      // 清空布局事件
      document.getElementById('clearLayout').addEventListener('click', () => {
        this.showAlert(
          '确认清空',
          `确定要清空${this.currentFloor === 'floor1' ? '1楼' : '2楼'}的布局吗？此操作不可恢复！`,
          'clearLayoutConfirm'
        );
      });
      
      // 编辑模式开关事件
      document.getElementById('editModeSwitch').addEventListener('change', (e) => {
        this.editMode = e.target.checked;
        // 更新UI
        document.getElementById('editControls').style.display = this.editMode ? 'block' : 'none';
        
        // 更新网格显示/隐藏
        const gridContainer = document.getElementById('gridContainer').parentElement;
        if (this.editMode) {
          gridContainer.classList.remove('hide-grid');
        } else {
          gridContainer.classList.add('hide-grid');
        }
        
        // 重新渲染座位和模块以显示/隐藏编辑按钮
        this.renderSeats();
        this.renderModules();
      });
      
      // 楼层切换事件
      document.getElementById('floor1').addEventListener('click', () => {
        this.currentFloor = 'floor1';
        this.renderSeats();
        this.renderModules();
      });
      
      document.getElementById('floor2').addEventListener('click', () => {
        this.currentFloor = 'floor2';
        this.renderSeats();
        this.renderModules();
      });
      
      // 保存按钮事件
      document.getElementById('saveChanges').addEventListener('click', () => {
        if (this.isEditingModule && this.currentModule) {
          // 保存模块
          const oldType = this.currentModule.type;
          const newType = document.getElementById('moduleType').value;
          const nameInput = document.getElementById('seatNumber');
          
          // 如果类型改变，或者使用的是默认名称，则自动更新名称
          const typeNames = this.getTypeNames();
          const isDefaultName = (
            this.currentModule.name === typeNames[oldType] || 
            this.currentModule.name === `${typeNames[oldType]}${this.modules[this.currentFloor].filter(m => m.type === oldType).length}`
          );
          
          if (oldType !== newType || isDefaultName) {
            // 设置新类型，然后生成名称
            this.currentModule.type = newType;
            nameInput.value = this.generateModuleName(newType);
          }
          
          this.currentModule.name = nameInput.value;
          this.currentModule.type = newType;
          this.saveToLocalStorage();
          this.renderModules();
        } else if (this.currentSeat) {
          // 保存座位
          this.currentSeat.number = document.getElementById('seatNumber').value;
          this.currentSeat.status = document.getElementById('seatStatus').value;
          this.saveToLocalStorage();
          this.renderSeats();
        }
        
        // 使用Bootstrap 5的方式关闭模态框
        const modal = bootstrap.Modal.getInstance(document.getElementById('editModal'));
        if (modal) modal.hide();
      });

      // 模块类型选择事件 - 自动更新名称
      document.getElementById('moduleType').addEventListener('change', (e) => {
        const moduleTypeSelect = e.target;
        const selectedType = moduleTypeSelect.value;
        const moduleNameInput = document.getElementById('seatNumber');
        
        // 根据选择的类型设置名称
        const typeNames = this.getTypeNames();
        moduleNameInput.value = typeNames[selectedType] || selectedType;
      });
      
      // 鼠标按下事件
      seatMap.addEventListener('mousedown', e => {
        // 只有在编辑模式下才可以拖动
        if (!this.editMode) return;
        
        // 判断是点击的座位还是模块
        const seatEl = e.target.closest('.seat-item');
        const moduleEl = e.target.closest('.module-item');
        
        if (!seatEl && !moduleEl) return;
        
        // 防止文本选择
        e.preventDefault();
        
        currentEl = seatEl || moduleEl;
        elementType = seatEl ? 'seat' : 'module';
        
        isDragging = true;
        startX = e.clientX;
        startY = e.clientY;
        initialX = currentEl.offsetLeft;
        initialY = currentEl.offsetTop;
        
        // 添加拖动时的样式
        currentEl.style.zIndex = '1000';
        currentEl.style.opacity = '0.8';
        // 禁用文本选择，避免拖动时出现蓝色选择框
        document.body.style.userSelect = 'none';
      });

      // 鼠标移动事件
      document.addEventListener('mousemove', e => {
        if (!isDragging) return;
        
        const dx = e.clientX - startX;
        const dy = e.clientY - startY;
        const newX = initialX + dx;
        const newY = initialY + dy;
        
        // 使用requestAnimationFrame优化性能
        requestAnimationFrame(() => {
          currentEl.style.left = `${newX}px`;
          currentEl.style.top = `${newY}px`;
        });
      });

      // 鼠标释放事件
      document.addEventListener('mouseup', () => {
        if (!isDragging) return;
        
        // 恢复样式
        currentEl.style.zIndex = '';
        currentEl.style.opacity = '1';
        // 恢复文本选择
        document.body.style.userSelect = '';
        
        // 获取ID和对象
        const itemId = parseInt(currentEl.querySelector('[data-id]').dataset.id);
        let item;
        
        if (elementType === 'seat') {
          item = this.seats[this.currentFloor].find(s => s.id === itemId);
        } else {
          item = this.modules[this.currentFloor].find(m => m.id === itemId);
        }

        if (!item) {
          isDragging = false;
          return;
        }

        // 计算最近的网格单元格
        const x = parseInt(currentEl.style.left);
        const y = parseInt(currentEl.style.top);
        
        // 找到最近的网格单元格
        const col = Math.round(x / this.cellSize);
        const row = Math.round(y / this.cellHeight);
        
        // 确保在网格范围内
        const validCol = Math.max(0, Math.min(col, this.gridCols - 1));
        const validRow = Math.max(0, Math.min(row, this.gridRows - 1));
        
        // 检查该位置是否已被占用
        if (this.isGridCellOccupied(validRow, validCol, item.id, elementType)) {
          // 如果被占用，找到最近的空闲单元格
          const freeCell = this.findNearestFreeCell(validRow, validCol);
          item.row = freeCell.row;
          item.col = freeCell.col;
        } else {
          // 如果未被占用，直接使用
          item.row = validRow;
          item.col = validCol;
        }
        
        // 更新元素位置到网格中心
        const newX = item.col * this.cellSize;
        const newY = item.row * this.cellHeight;
        currentEl.style.left = `${newX}px`;
        currentEl.style.top = `${newY}px`;
        
        this.saveToLocalStorage();
        isDragging = false;
      });
      
      // 点击事件处理（编辑和删除）
      seatMap.addEventListener('click', e => {
        // 编辑按钮 - 只有在编辑模式下才有效
        if (this.editMode && e.target.classList.contains('edit-btn')) {
          const itemId = parseInt(e.target.dataset.id);
          const itemType = e.target.dataset.type;
          
          if (itemType === 'seat') {
            this.currentSeat = this.seats[this.currentFloor].find(s => s.id === itemId);
            this.currentModule = null;
            this.isEditingModule = false;
            if (this.currentSeat) {
              this.showEditModal('seat');
            }
          } else {
            this.currentModule = this.modules[this.currentFloor].find(m => m.id === itemId);
            this.currentSeat = null;
            this.isEditingModule = true;
            if (this.currentModule) {
              this.showEditModal('module');
            }
          }
        } 
        // 删除按钮 - 只有在编辑模式下才有效
        else if (this.editMode && e.target.classList.contains('delete-icon')) {
          const itemId = parseInt(e.target.dataset.id);
          const itemType = e.target.dataset.type;
          
          if (itemType === 'seat') {
            this.showAlert('删除确认', '确定要删除这个座位吗？', 'removeSeat', itemId);
          } else if (itemType === 'module') {
            this.showAlert('删除确认', '确定要删除这个模块吗？', 'removeModule', itemId);
          }
        }
      });
    }

    isGridCellOccupied(row, col, excludeItemId = null, itemType = null) {
      // 检查座位
      const seatOccupied = this.seats[this.currentFloor].some(seat => 
        seat.row === row && 
        seat.col === col && 
        (excludeItemId === null || seat.id !== excludeItemId || itemType !== 'seat')
      );
      
      // 检查模块
      const moduleOccupied = this.modules[this.currentFloor].some(module => 
        module.row === row && 
        module.col === col && 
        (excludeItemId === null || module.id !== excludeItemId || itemType !== 'module')
      );
      
      return seatOccupied || moduleOccupied;
    }

    findNearestFreeCell(startRow, startCol) {
      // 螺旋搜索算法，从中心向外扩展
      let direction = 0; // 0: 右, 1: 下, 2: 左, 3: 上
      let steps = 1;
      let stepCount = 0;
      let row = startRow;
      let col = startCol;
      
      while (true) {
        // 检查当前单元格是否在网格范围内且未被占用
        if (row >= 0 && row < this.gridRows && 
            col >= 0 && col < this.gridCols && 
            !this.isGridCellOccupied(row, col)) {
          return { row, col };
        }
        
        // 按当前方向移动
        switch (direction) {
          case 0: col++; break; // 右
          case 1: row++; break; // 下
          case 2: col--; break; // 左
          case 3: row--; break; // 上
        }
        
        stepCount++;
        
        // 当完成一个方向的步数后，改变方向
        if (stepCount === steps) {
          stepCount = 0;
          direction = (direction + 1) % 4;
          
          // 每完成两个方向，增加步数
          if (direction === 0 || direction === 2) {
            steps++;
          }
        }
        
        // 安全检查，防止无限循环
        if (steps > Math.max(this.gridRows, this.gridCols) * 2) {
          // 如果找不到空闲单元格，返回(0,0)
          return { row: 0, col: 0 };
        }
      }
    }

    showEditModal(type = 'seat') {
      const modal = document.getElementById('editModal');
      const statusGroup = document.getElementById('statusGroup');
      const moduleTypeGroup = document.getElementById('moduleTypeGroup');
      
      // 更新模态框标题
      modal.querySelector('.modal-title').textContent = type === 'seat' ? '座位设置' : '模块设置';
      
      // 显示/隐藏相应的字段
      if (type === 'seat') {
        statusGroup.style.display = 'block';
        moduleTypeGroup.style.display = 'none';
        
        if (this.currentSeat) {
          document.getElementById('seatNumber').value = this.currentSeat.number || '';
          document.getElementById('seatStatus').value = this.currentSeat.status || 'online';
        }
      } else {
        statusGroup.style.display = 'none';
        moduleTypeGroup.style.display = 'block';
        
        if (this.currentModule) {
          document.getElementById('seatNumber').value = this.currentModule.name || '';
          document.getElementById('moduleType').value = this.currentModule.type || 'wall';
        }
      }
      
      // 使用Bootstrap 5的方式显示模态框
      const bsModal = new bootstrap.Modal(document.getElementById('editModal'));
      bsModal.show();

      // 添加回车键事件监听
      const handleKeyPress = (e) => {
        if (e.key === 'Enter') {
          document.getElementById('saveChanges').click();
          document.removeEventListener('keypress', handleKeyPress);
        }
      };
      document.addEventListener('keypress', handleKeyPress);
    }

    addSeat() {
      // 找到一个空闲的网格单元格
      let row = 0;
      let col = 0;
      
      // 寻找第一个空闲单元格
      for (let r = 0; r < this.gridRows; r++) {
        for (let c = 0; c < this.gridCols; c++) {
          if (!this.isGridCellOccupied(r, c)) {
            row = r;
            col = c;
            break;
          }
        }
      }
      
      // 创建新座位
      const newSeat = {
        id: this.nextId++,
        number: `${this.currentFloor === 'floor1' ? 'A' : 'B'}${this.seats[this.currentFloor].length + 1}`,
        status: 'online',
        row: row,
        col: col,
        floor: this.currentFloor
      };

      this.seats[this.currentFloor].push(newSeat);
      this.saveToLocalStorage();
      this.renderSeats();

      // 高亮新添加的座位
      setTimeout(() => {
        const seatEl = document.querySelector(`.seat-item:last-child`);
        if (seatEl) {
          seatEl.classList.add('flash');
          setTimeout(() => {
            seatEl.classList.remove('flash');
          }, 500);
        }
      }, 0);
    }
    
    addCustomModule() {
      // 找到一个空闲的网格单元格
      let row = 0;
      let col = 0;
      
      // 寻找第一个空闲单元格
      for (let r = 0; r < this.gridRows; r++) {
        for (let c = 0; c < this.gridCols; c++) {
          if (!this.isGridCellOccupied(r, c)) {
            row = r;
            col = c;
            break;
          }
        }
      }
      
      // 创建新模块
      const moduleType = 'wall'; // 默认为墙体
      const moduleName = this.generateModuleName(moduleType);
      
      const newModule = {
        id: this.nextId++,
        name: moduleName,
        type: moduleType,
        row: row,
        col: col,
        floor: this.currentFloor
      };

      this.modules[this.currentFloor].push(newModule);
      this.saveToLocalStorage();
      this.renderModules();

      // 高亮新添加的模块
      setTimeout(() => {
        const moduleEl = document.querySelector(`.module-item:last-child`);
        if (moduleEl) {
          moduleEl.classList.add('flash');
          setTimeout(() => {
            moduleEl.classList.remove('flash');
          }, 500);
        }
      }, 0);
    }

    removeSeat(seatId) {
      this.seats[this.currentFloor] = this.seats[this.currentFloor].filter(s => s.id !== seatId);
      this.saveToLocalStorage();
      this.renderSeats();
    }
    
    removeModule(moduleId) {
      this.modules[this.currentFloor] = this.modules[this.currentFloor].filter(m => m.id !== moduleId);
      this.saveToLocalStorage();
      this.renderModules();
    }

    saveToLocalStorage() {
      try {
        // 分别保存每个楼层的数据
        localStorage.setItem('seats_floor1', JSON.stringify(this.seats.floor1));
        localStorage.setItem('seats_floor2', JSON.stringify(this.seats.floor2));
        
        // 保存模块数据
        localStorage.setItem('modules_floor1', JSON.stringify(this.modules.floor1));
        localStorage.setItem('modules_floor2', JSON.stringify(this.modules.floor2));
      } catch (error) {
        console.error('保存数据失败:', error);
        // 使用更友好的错误提示
        const errorMsg = document.createElement('div');
        errorMsg.className = 'alert alert-danger';
        errorMsg.textContent = '保存失败，请重试';
        document.querySelector('.col-12').prepend(errorMsg);
        
        // 3秒后自动移除错误提示
        setTimeout(() => {
          errorMsg.remove();
        }, 3000);
      }
    }
    
    // 导出座位布局为JSON文件
    exportLayout() {
      try {
        // 转换为更易读的格式
        const exportData = {
          floor1: {
            seats: this.seats.floor1.map(seat => ({
              id: seat.id,
              number: seat.number,
              status: seat.status,
              position: `${seat.row}:${seat.col}`,
              floor: 'floor1'
            })),
            modules: this.modules.floor1.map(module => ({
              id: module.id,
              name: module.name,
              type: module.type,
              position: `${module.row}:${module.col}`,
              floor: 'floor1'
            }))
          },
          floor2: {
            seats: this.seats.floor2.map(seat => ({
              id: seat.id,
              number: seat.number,
              status: seat.status,
              position: `${seat.row}:${seat.col}`,
              floor: 'floor2'
            })),
            modules: this.modules.floor2.map(module => ({
              id: module.id,
              name: module.name,
              type: module.type,
              position: `${module.row}:${module.col}`,
              floor: 'floor2'
            }))
          }
        };
        
        const dataStr = JSON.stringify(exportData, null, 2);
        const dataUri = 'data:application/json;charset=utf-8,'+ encodeURIComponent(dataStr);
        
        const exportFileDefaultName = 'layout.json';
        
        const linkElement = document.createElement('a');
        linkElement.setAttribute('href', dataUri);
        linkElement.setAttribute('download', exportFileDefaultName);
        linkElement.click();
      } catch (error) {
        console.error('导出失败:', error);
        alert('导出失败，请重试');
      }
    }
    
    // 处理导入按钮点击
    handleImport() {
      const input = document.createElement('input');
      input.type = 'file';
      input.accept = '.json';
      input.onchange = e => {
        const file = e.target.files[0];
        if (file) {
          const reader = new FileReader();
          reader.onload = event => {
            const success = this.importLayout(event.target.result);
            if (success) {
              alert('导入成功！');
            } else {
              alert('导入失败，请检查文件格式！');
            }
          };
          reader.readAsText(file);
        }
      };
      input.click();
    }
    
    // 导入座位布局
    importLayout(jsonData) {
      try {
        const data = JSON.parse(jsonData);
        
        // 新格式 (包含floor1和floor2，以及每个楼层的seats和modules)
        if (data.floor1 && data.floor2) {
          if (data.floor1.seats && data.floor1.modules) {
            // 新格式
            this.seats.floor1 = data.floor1.seats.map(item => this.convertImportedSeat(item, 'floor1'));
            this.modules.floor1 = data.floor1.modules.map(item => this.convertImportedModule(item, 'floor1'));
            
            this.seats.floor2 = data.floor2.seats.map(item => this.convertImportedSeat(item, 'floor2'));
            this.modules.floor2 = data.floor2.modules.map(item => this.convertImportedModule(item, 'floor2'));
          } else {
            // 旧格式
            this.seats.floor1 = data.floor1.map(item => this.convertImportedSeat(item, 'floor1'));
            this.seats.floor2 = data.floor2.map(item => this.convertImportedSeat(item, 'floor2'));
            
            // 清空模块数据
            this.modules.floor1 = [];
            this.modules.floor2 = [];
          }
        } 
        // 处理旧格式（单一数组）
        else if (Array.isArray(data)) {
          // 假设所有座位都是当前楼层的
          this.seats[this.currentFloor] = data.map(item => this.convertImportedSeat(item, this.currentFloor));
          // 清空模块数据
          this.modules[this.currentFloor] = [];
        } else {
          return false;
        }
        
        // 更新nextId
        const allItems = [...this.seats.floor1, ...this.seats.floor2, ...this.modules.floor1, ...this.modules.floor2];
        if (allItems.length > 0) {
          const maxId = Math.max(...allItems.map(item => item.id));
          this.nextId = maxId + 1;
        }
        
        this.saveToLocalStorage();
        this.renderSeats();
        this.renderModules();
        return true;
      } catch (error) {
        console.error('导入失败:', error);
        return false;
      }
    }
    
    // 转换导入的座位数据
    convertImportedSeat(item, defaultFloor) {
      // 处理两种可能的格式：新格式(row/col)和旧格式(position字符串)
      let row = 0, col = 0;
      
      if (item.row !== undefined && item.col !== undefined) {
        // 新格式
        row = item.row;
        col = item.col;
      } else if (item.position) {
        // 旧格式 "row:col"
        const [r, c] = item.position.split(':').map(Number);
        row = r;
        col = c;
      }
      
      return {
        id: item.id || this.nextId++,
        number: item.number || `Seat-${this.nextId}`,
        status: item.status || 'online',
        row: row,
        col: col,
        floor: item.floor || defaultFloor
      };
    }
    
    // 转换导入的模块数据
    convertImportedModule(item, defaultFloor) {
      // 处理两种可能的格式：新格式(row/col)和旧格式(position字符串)
      let row = 0, col = 0;
      
      if (item.row !== undefined && item.col !== undefined) {
        // 新格式
        row = item.row;
        col = item.col;
      } else if (item.position) {
        // 旧格式 "row:col"
        const [r, c] = item.position.split(':').map(Number);
        row = r;
        col = c;
      }
      
      // 类型映射 - 兼容旧格式
      const typeMapping = {
        'door': 'entrance',  // 旧的出入口映射到新的
        'aisle': 'stairs'    // 旧的过道映射到楼梯
      };
      
      // 确保类型有效，否则默认为墙体
      const validTypes = ['wall', 'entrance', 'testing', 'stairs', 'toilet', 'reception'];
      let moduleType = item.type || 'wall';
      // 应用类型映射
      moduleType = typeMapping[moduleType] || moduleType;
      // 如果映射后仍然不是有效类型，则默认为墙体
      if (!validTypes.includes(moduleType)) {
        moduleType = 'wall';
      }
      
      // 根据类型确定名称
      const typeNames = {
        'wall': '墙体',
        'entrance': '出入口',
        'testing': '测试区',
        'stairs': '楼梯',
        'toilet': '厕所',
        'reception': '前台'
      };
      
      return {
        id: item.id || this.nextId++,
        // 如果原有名称与默认名称不同，保留原有名称
        name: item.name || typeNames[moduleType] || `Module-${this.nextId}`,
        type: moduleType,
        row: row,
        col: col,
        floor: item.floor || defaultFloor
      };
    }
    
    // 清空布局确认回调
    clearLayoutConfirm() {
      this.seats[this.currentFloor] = [];
      this.modules[this.currentFloor] = [];
      this.saveToLocalStorage();
      this.renderSeats();
      this.renderModules();
    }

    // 清空布局
    clearLayout() {
      this.showAlert(
        '确认清空',
        `确定要清空${this.currentFloor === 'floor1' ? '1楼' : '2楼'}的布局吗？此操作不可恢复！`,
        'clearLayoutConfirm'
      );
    }

    // 初始化自定义弹窗事件
    initCustomAlert() {
      const overlay = document.getElementById('alertOverlay');
      const alertBox = document.getElementById('customAlert');
      const cancelBtn = document.getElementById('alertCancel');
      const confirmBtn = document.getElementById('alertConfirm');
      
      // 取消按钮事件
      cancelBtn.addEventListener('click', () => {
        this.hideAlert();
      });
      
      // 点击遮罩关闭弹窗
      overlay.addEventListener('click', () => {
        this.hideAlert();
      });
      
      // 按下ESC键关闭弹窗
      document.addEventListener('keydown', (e) => {
        if (e.key === 'Escape' && alertBox.style.display === 'block') {
          this.hideAlert();
        }
        // 按下Enter键确认
        if (e.key === 'Enter' && alertBox.style.display === 'block') {
          const confirmCallback = alertBox.getAttribute('data-callback');
          if (confirmCallback && this[confirmCallback]) {
            this[confirmCallback](alertBox.getAttribute('data-param'));
          }
          this.hideAlert();
        }
      });
    }
    
    // 显示自定义弹窗
    showAlert(title, message, confirmCallback, param = null) {
      const overlay = document.getElementById('alertOverlay');
      const alertBox = document.getElementById('customAlert');
      const alertTitle = document.getElementById('alertTitle');
      const alertMessage = document.getElementById('alertMessage');
      const confirmBtn = document.getElementById('alertConfirm');
      const cancelBtn = document.getElementById('alertCancel');
      
      // 设置内容
      alertTitle.textContent = title || '提示';
      alertMessage.textContent = message || '确定执行此操作吗？';
      
      // 设置确认回调
      if (confirmCallback && this[confirmCallback]) {
        confirmBtn.onclick = () => {
          this[confirmCallback](param);
          this.hideAlert();
        };
        alertBox.setAttribute('data-callback', confirmCallback);
        alertBox.setAttribute('data-param', param);
      }
      
      // 设置取消按钮事件
      cancelBtn.onclick = () => {
        this.hideAlert();
      };
      
      // 显示弹窗
      overlay.style.display = 'block';
      alertBox.style.display = 'block';
    }
    
    // 隐藏自定义弹窗
    hideAlert() {
      const overlay = document.getElementById('alertOverlay');
      const alertBox = document.getElementById('customAlert');
      
      overlay.style.display = 'none';
      alertBox.style.display = 'none';
    }

    getTypeNames() {
      return {
        'wall': '墙体',
        'entrance': '出入口',
        'testing': '测试区',
        'stairs': '楼梯',
        'toilet': '厕所',
        'reception': '前台'
      };
    }
    
    // 获取座位在网格中的位置信息
    getSeatGridPosition(seatId, floor = null) {
      const floorToCheck = floor || this.currentFloor;
      const seat = this.seats[floorToCheck].find(s => s.id === seatId);
      if (seat) {
        return {
          row: seat.row,
          col: seat.col,
          position: `${seat.row}:${seat.col}`,
          floor: floorToCheck
        };
      }
      return null;
    }
    
    // 自动生成模块名称
    generateModuleName(moduleType) {
      const typeNames = this.getTypeNames();
      return typeNames[moduleType] || moduleType;
    }
  }

  // 初始化座位管理器
  document.addEventListener('DOMContentLoaded', () => {
    const seatManager = new SeatManager();
  });
</script>

</body>

</html>